﻿using Demo.Core.CommonExtension;

namespace Demo.Core.CommonFunction;

/// <summary>
/// 集合比对
/// </summary>
public class ListCompare
{
    /*
     * 调用实例：
     *  MutiCompare<Permission, string>(lst1, lst2, x => x.Code, (obj, isnew) =>
     *  {
     *      if (isnew)
     *      {
     *          Console.WriteLine($"新增项{obj.Id}");
     *      }
     *      else
     *      {
     *          Console.WriteLine($"已存在{obj.Id}");
     *      }
     *  }, out var lstNeedRemove);
     */
    /// <summary>
    /// 对比源集合和目标集合，处理已有项和新增项，并找出需要删除的项
    /// </summary>
    /// <param name="lstSource">源集合</param>
    /// <param name="lstDestination">目标集合</param>
    /// <param name="keySelector">集合比对关键字</param>
    /// <param name="action">新增或已有项处理方法，参数：（数据项, 是否是新增）</param>
    /// <param name="needRemove">需要删除的数据集</param>
    /// <typeparam name="TObject">集合对象数据类型</typeparam>
    /// <typeparam name="TKey">对比关键字数据类型</typeparam>
    public static void MutiCompare<TObject,TKey>(List<TObject> lstDestination,List<TObject> lstSource,
        Func<TObject, TKey> keySelector,
        Action<TObject, bool> action, 
        out Dictionary<TKey, TObject> needRemove)
    {
        //目标集合去重
        lstDestination.Distinct(keySelector);
        //将源集合存入字典，提高查询效率
        needRemove = new Dictionary<TKey, TObject>();
        foreach (var item in lstSource)
        {
            needRemove.Add(keySelector(item),item);
        }
        //遍历目标集合，区分新增项及已有项
        //在字典中排除目标集合中的项，剩余的即为源集合中需删除的项
        foreach (var item in lstDestination)
        {
            if (needRemove.ContainsKey(keySelector(item)))
            {
                action(item, false);
                needRemove.Remove(keySelector(item));
            }
            else
            {
                action(item, true);
            }
        }
    }
}